package com.dengqi.mymodule.activity.asynctask;

import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import com.dengqi.mymodule.BaseActivity;
import com.dengqi.mymodule.R;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 坑：task只能执行一次，需要执行多次需要重新创建对象
 */
public class AsyncTaskActivity extends BaseActivity {


    private ImageView image;
    private String url = "http://desk.fd.zol-img.com.cn/t_s1920x1080/g2/M00/09/03/ChMlWly11BOIS94cAAGnTjeBTcsAAJesAJ4XEwAAadm254.jpg";
    private String url2 = "http://desk.fd.zol-img.com.cn/t_s1920x1080/g2/M00/0D/0F/ChMlWlyJq3WIFK4ZAAYH7JAhXXcAAIx6wGV39YABggE583.jpg";
    private ProgressDialog progressDialog;
    private DownloadTask downloadTask;
    private MyAsyncTask myAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_asynctask);
        image = findViewById(R.id.image);
        progressDialog = new ProgressDialog(this);
        progressDialog.setTitle("提示信息");
        progressDialog.setMessage("正在下载中，请稍后......");
        //    设置setCancelable(false); 表示我们不能取消这个弹出框，等下载完成之后再让弹出框消失
        progressDialog.setCancelable(true);
        //    设置ProgressDialog样式为圆圈的形式
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    }

    /**
     * 方法一
     */
    public void onBtn1(View view) {
        myAsyncTask = new MyAsyncTask(this);
        myAsyncTask.execute(url);
    }

    /**
     * 方法二
     */
    public void onBtn2(View view) {
        downloadTask = new DownloadTask(new TaskListener() {
            @Override
            public void onPreExecute() {
                progressDialog.setProgress(0);
                progressDialog.show();
            }

            @Override
            public void onProgressUpdate(int progress) {
                progressDialog.setProgress(progress);
            }

            @Override
            public void onPostExecute(Bitmap bitmap) {
                progressDialog.dismiss();
                image.setImageBitmap(bitmap);
            }
        });
        downloadTask.execute(url2);
    }

    /**
     * 进阶
     * 1.默认串行执行
     * 2.executeOnExecutor并发执行
     * 3.默认5个线程同时执行，执行完毕后重用原来的线程
     * @param view
     */
    public void onBtn3(View view) {
        //为每个任务分配一个线程
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        //最多开启3个线程，执行完毕后重用原来的线程
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 1; i < 11; i++) {
            MultiAsyncTask task = new MultiAsyncTask("task" + i);
//            task.execute(new String[0]);
//            task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, new String[0]); //同task.execute(new String[0]);
//            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[0]);
//            task.executeOnExecutor(newCachedThreadPool, new String[0]);
            task.executeOnExecutor(newFixedThreadPool, new String[0]);
        }
        Log.e("---", "方法执行完毕");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (downloadTask != null && downloadTask.isCancelled()) {
            //只是把isCancel标记为true，还需要置空
            downloadTask.cancel(true);
            downloadTask = null;
        }
        if (myAsyncTask != null && myAsyncTask.isCancelled()) {
            myAsyncTask.cancel(true);
            myAsyncTask = null;
        }
    }

    /**
     * task劫持activity的两种可能
     * 1.task执行时间长，activity销毁时 task会劫持activity
     * 解决：采用静态类+若引用
     * 2.activity关闭时需要task=null 否则task会劫持activity
     * 解决：task.cancel(true); task=null
     *
     * 注：非静态内部类会劫持外部类 所以需要加上static,
     * Activity/View需要加上WeakReference
     */
    private static class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {

        private WeakReference<AsyncTaskActivity> activityReference;
        private WeakReference<ImageView> imageReference;
        private WeakReference<ProgressDialog> progressDialogReference;

        MyAsyncTask(AsyncTaskActivity context) {
            activityReference = new WeakReference<>(context);
            imageReference = new WeakReference<>((ImageView) activityReference.get().findViewById(R.id.image));
            ProgressDialog progressDialog = new ProgressDialog(activityReference.get());
            progressDialog.setTitle("提示信息");
            progressDialog.setMessage("正在下载中，请稍后......");
            //    设置setCancelable(false); 表示我们不能取消这个弹出框，等下载完成之后再让弹出框消失
            progressDialog.setCancelable(true);
            //    设置ProgressDialog样式为圆圈的形式
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialogReference = new WeakReference<>(progressDialog);
        }

        /**
         * 相关的准备任务，运行在 UI 线程
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialogReference.get().setProgress(0);
            progressDialogReference.get().show();
        }

        /**
         * 代理 异步任务，运行在独立的线程中，期中可以使用publishProgress(int) 方法更新任务进度
         */
        @Override
        protected Bitmap doInBackground(String... strings) {
            //    通过Apache的HttpClient来访问请求网络中的一张图片
            HttpURLConnection connection;
            Bitmap bitmap = null;
            try {
                URL url = new URL(strings[0]);
                connection = (HttpURLConnection) url.openConnection();
                connection.setUseCaches(false);
                InputStream inputStream = connection.getInputStream();
                //方法一
//                bitmap = BitmapFactory.decodeStream(inputStream);
                //方法二
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                // 得到文件的总长度
                int file_length = connection.getContentLength();
                // 每次读取后累加的长度
                int total_length = 0;
                int length = 0;
                byte[] buffer = new byte[1024];
                while ((length = inputStream.read(buffer)) != -1) {
                    // 每读一次，就将total_length累加起来
                    total_length += length;
                    // 边读边写到ByteArrayOutputStream当中
                    byteArrayOutputStream.write(buffer, 0, length);
                    // 得到当前图片下载的进度
                    int progress = (int) ((total_length / (float) file_length) * 100);
                    // 时刻将当前进度更新给onProgressUpdate方法
                    publishProgress(progress);
                }
                bitmap = BitmapFactory.decodeByteArray(byteArrayOutputStream.toByteArray(), 0, file_length);
                inputStream.close();
                byteArrayOutputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bitmap;
        }


        /**
         * 用于更新进度，运行在 UI 线程
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            progressDialogReference.get().setProgress(values[0]);
        }

        /**
         * 获取最终结果，运行在 UI 线程
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            // 重新获取Actiity的强引用，并且判断是否存活
            AsyncTaskActivity activity = activityReference.get();
            if (activity == null
                    || activity.isFinishing()) {
                // activity死亡了，不再做任何的事情
                return;
            }
            // The activity is still valid, do main-thread stuff here
            progressDialogReference.get().dismiss();
            imageReference.get().setImageBitmap(bitmap);
        }
    }
}
